package org.lanqiao.tjut.myUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class MyUtils {

	/**
	 * 公共方法：将查询结果集Resultset转换list+map的数据结构
	 * 
	 * @param rs
	 *            被转化的查询结果集
	 * @return list数据结构
	 */
	public static List<Map<String, Object>> convertResultSet2ListMap(ResultSet rs) {
		// 创建返回的List对象
		List<Map<String, Object>> lst = new ArrayList<Map<String, Object>>();
		try {
			// 遍历rs，将rs中的结果集转换list+map的数据结构
			// 获取与列相关的信息
			ResultSetMetaData rsmd = rs.getMetaData();
			// 获取查询结果集的列数
			int colCount = rsmd.getColumnCount();
			// 遍历结果集的行
			while (rs != null && rs.next()) {
				// 创建一个map对象用于存储当前行的列集合
				Map<String, Object> map = new LinkedHashMap<String, Object>();
				// 使用for循环输出当前结果集中当前行中所有的列信息
				for (int i = 1; i <= colCount; i++) {
					map.put(rsmd.getColumnLabel(i), rs.getObject(rsmd.getColumnLabel(i)));
				}
				// 将map存入list中
				lst.add(map);
			}
		} catch (Exception e) {
			// Resultset转换为List异常
			System.out.println("Oracle-Jdbc-Resultset转换为List异常：");
			e.printStackTrace();
		}
		return lst;
	}

	/**
	 * 公共方法：将查询结果集Resultset转换list+map的数据结构
	 * @param <T>
	 *          转换的实体类的泛型
	 * @param rs
	 *            被转化的查询结果集
	 * @return list数据结构
	 */
	public static <T> List<T> convertResultSet2ListBean(ResultSet rs, Class<T> beanClass) {
		// 创建返回的List对象
		List<T> lst = new ArrayList<T>();
		try {
			// 遍历rs，将rs中的结果集转换list+map的数据结构
			// 获取与列相关的信息
			ResultSetMetaData rsmd = rs.getMetaData();
			// 获取查询结果集的列数
			int colCount = rsmd.getColumnCount();
			// 遍历结果集的行
			while (rs != null && rs.next()) {
				// 创建一个beanClass的实例变量，用于存储结果集中的一行数据记录
				// 泛型  T 表示实体类类型
				T objBean = beanClass.newInstance();
				// 使用for循环输出当前结果集中当前行中所有的列信息
				for (int i = 1; i <= colCount; i++) {
					// 使用反射机制，给objBean的各个属性进行赋值
					/*
					 * 映射规则： 
					 * 实体类的属性和数据库表中的字段名相同(忽略大小写) 
					 * 也就是，实体类的属性名师数据库字段名的小写形式；
					 */
					// 取出当前列的名
					String colName = rsmd.getColumnLabel(i);
					if (colName != null && !colName.equals("")) {
						// 使用反射，获取与字段名colName对象的实体类的属性名
						Field fColName = beanClass.getDeclaredField(colName.toLowerCase());
						// 使用反射，获取属性的数据类型
						Class cColNameType = fColName.getType();
						// 属性的set方法名---setXxxx
						String strColNameSetter = "set" + colName.substring(0, 1).toUpperCase()
								+ colName.substring(1).toLowerCase();
						// 使用反射，获取属性的set方法
						Method mColName = beanClass.getDeclaredMethod(strColNameSetter, cColNameType);
						// 使用反射的invoke机制，调用set方法给该属性进行赋值
						mColName.invoke(objBean, parseType(rs.getObject(rsmd.getColumnLabel(i))));
					}
				}
				// 将实体类对象存入list中
				lst.add(objBean);
			}
		} catch (Exception e) {
			// Resultset转换为List异常
			System.out.println("Oracle-Jdbc-Resultset转换为List异常：");
			e.printStackTrace();
		}
		return lst;
	}

	/**
	 * 将数据库的数据类型转换为Java的数据类型
	 * 
	 * @param resObj
	 *            数据库类型的对象
	 * @return 转换之后的Java类型的对象
	 */
	private static Object parseType(Object resObj) {
		/*
		 * 该方法需要扩展其他Oracle jdbc的数据类型转换处理
		 * 
		 */
		// 返回值
		Object obj = null;
		if (resObj != null) {
			// 数据库的源类型
			String strResType = resObj.getClass().getName();
			switch (strResType) {
			case "java.math.BigDecimal":
				obj = Integer.valueOf(resObj.toString());
				break;
			case "java.sql.Date":
			case "java.sql.Time":
			case "javal.sql.Timestamp":
				// TODO 需要调试扩展
				obj = null;
				break;
			default:
				obj = resObj.toString();
				break;
			}
		}
		// 返回值
		return obj;
	}

}
